package com.smart.cosstarter.aspect;

import com.cue.es.oss.annotation.*;
import com.smart.cosstarter.annotation.*;
import com.smart.cosstarter.config.COSObjectManager;
import com.smart.cosstarter.config.ServiceInjectProcessor;
import com.smart.cosstarter.constance.DefaultBuckets;
import com.smart.cosstarter.exception.NoBucketExeception;
import com.smart.cosstarter.exception.NoFileException;
import com.smart.cosstarter.exception.NoKeyException;
import com.smart.cosstarter.exception.NonacceptanceException;
import com.smart.cosstarter.model.DownObjectRequest;
import com.qcloud.cos.model.COSObject;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.model.UploadResult;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

import java.io.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

/**
 * @Author: jj
 * @Date: 2019/8/7 15:15
 * @Version 1.0
 */
@Component
@Aspect
public class ObjectAspect {

	@Autowired
	private COSObjectManager cosObjectManager;

	@Autowired
	private ServiceInjectProcessor serviceInjectProcessor;

	@Pointcut("@annotation(com.smart.cosstarter.annotation.UploadRemoveSrc)")
	public void uploadRemoveSreAspectMethod() {
	}

	@Pointcut("@annotation(com.smart.cosstarter.annotation.Upload)")
	public void uploadAspectMethod() {
	}

	@Pointcut("@annotation(com.smart.cosstarter.annotation.DownloadRemoveSrc)")
	public void downloadRemoveSreAspectMethod() {
	}

	@Pointcut("@annotation(com.smart.cosstarter.annotation.Download)")
	public void downloadAspectMethod() {
	}

	@Pointcut("@within(com.smart.cosstarter.annotation.UseCOS)")
	public void useBucketAspect() {
	}


	@AfterReturning(pointcut = "uploadAspectMethod()", returning = "ret")
	public Object uploadAspectAfter(JoinPoint joinPoint, Object ret) {

		MethodSignature signature = (MethodSignature) joinPoint.getSignature();
		Method method = signature.getMethod();
		Class<?> targetClass = joinPoint.getTarget().getClass();
		UseCOS useBucketAnnotation = AnnotationUtils.findAnnotation(targetClass, UseCOS.class);
		Upload uploadAnnotation = AnnotationUtils.findAnnotation(method, Upload.class);
		Object[] arguments = joinPoint.getArgs();
		String bucketName = DefaultBuckets.bucket;
		if (useBucketAnnotation.bucketName() != null && !"".equals(useBucketAnnotation.bucketName())) {
			bucketName = useBucketAnnotation.bucketName();
		}
		UploadResult uploadResult = null;
		if (uploadAnnotation.bucketName() != null && !"".equals(uploadAnnotation.bucketName())) {
			bucketName = uploadAnnotation.bucketName();
		}
		if (arguments.length == 1) {
			if ("".equals(bucketName)) {
				throw new NoBucketExeception();
			}
			if (arguments[0] instanceof File) {
				File argument = (File) arguments[0];
				String key = argument.getName();
				if (!"".equals(uploadAnnotation.key())) {
					if (uploadAnnotation.key().endsWith("/")) {
						key = uploadAnnotation.key() + key;
					} else {
						key = uploadAnnotation.key();
					}
				}
				try {
					if (uploadAnnotation.asyn()) {
						uploadResult = cosObjectManager.asynchUpload(bucketName, key, argument);
					} else {
						uploadResult = cosObjectManager.synchUpload(bucketName, key, argument);
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			} else if (arguments[0] instanceof PutObjectRequest) {
				try {
					if (uploadAnnotation.asyn()) {
						uploadResult = cosObjectManager.asynchUpload((PutObjectRequest) arguments[0]);
					} else {
						uploadResult = cosObjectManager.synchUpload((PutObjectRequest) arguments[0]);
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			} else {
				try {
					//将对象写到流里
					ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
					ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
					objOut.writeObject(arguments[0]);
					//从流里读出来
					ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
					ObjectInputStream objInput = new ObjectInputStream(byteIn);
					ObjectMetadata metadata = new ObjectMetadata();
					metadata.addUserMetadata("type", method.getParameterTypes()[0].getTypeName());
					PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, uploadAnnotation.key(), objInput, metadata);
					if (uploadAnnotation.asyn()) {
						uploadResult = cosObjectManager.asynchUpload(putObjectRequest);
					} else {
						uploadResult = cosObjectManager.synchUpload(putObjectRequest);
					}
				} catch (IOException e) {
					e.printStackTrace();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		} else {
			try {
				if (arguments.length == 3 && arguments[0] instanceof String && arguments[1] instanceof String && arguments[2] instanceof File) {
					if (uploadAnnotation.asyn()) {
						uploadResult = cosObjectManager.asynchUpload((String) arguments[0], (String) arguments[1], (File) arguments[2]);
					} else {
						uploadResult = cosObjectManager.synchUpload((String) arguments[0], (String) arguments[1], (File) arguments[2]);
					}
				}
				if (arguments.length == 4 && arguments[0] instanceof String && arguments[1] instanceof String
						&& arguments[2] instanceof InputStream && arguments[3] instanceof ObjectMetadata) {
					if (uploadAnnotation.asyn()) {
						uploadResult = cosObjectManager.asynchUpload((String) arguments[0],
								(String) arguments[1], (InputStream) arguments[2], (ObjectMetadata) arguments[2]);
					} else {
						uploadResult = cosObjectManager.synchUpload((String) arguments[0],
								(String) arguments[1], (InputStream) arguments[2], (ObjectMetadata) arguments[2]);
					}
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		if (method.getGenericReturnType().getTypeName().equals(UploadResult.class.getTypeName())) {
			return uploadResult;
		}
		if (method.getGenericReturnType().getTypeName().equals(Object.class.getTypeName())) {
			return uploadResult;
		}
		if (method.getGenericReturnType().getTypeName().equals(String.class.getTypeName())) {
			return uploadResult.toString();
		}
		return ret;
	}

	@AfterReturning(pointcut = "uploadRemoveSreAspectMethod()", returning = "ret")
	public Object uploadRemoveSreAspectAfter(JoinPoint joinPoint, Object ret) {

		MethodSignature signature = (MethodSignature) joinPoint.getSignature();
		Method method = signature.getMethod();
		Class<?> targetClass = joinPoint.getTarget().getClass();
		UseCOS useBucketAnnotation = AnnotationUtils.findAnnotation(targetClass, UseCOS.class);
		UploadRemoveSrc uploadAnnotation = AnnotationUtils.findAnnotation(method, UploadRemoveSrc.class);
		Object[] arguments = joinPoint.getArgs();
		String bucketName = DefaultBuckets.bucket;
		if (useBucketAnnotation.bucketName() != null && !"".equals(useBucketAnnotation.bucketName())) {
			bucketName = useBucketAnnotation.bucketName();
		}
		UploadResult uploadResult = null;
		if (uploadAnnotation.bucketName() != null && !"".equals(uploadAnnotation.bucketName())) {
			bucketName = uploadAnnotation.bucketName();
		}
		if (arguments.length == 1) {
			if ("".equals(bucketName)) {
				throw new NoBucketExeception();
			}
			if (arguments[0] instanceof File) {
				String key = ((File) arguments[0]).getName();
				if (!"".equals(uploadAnnotation.key())) {
					if (uploadAnnotation.key().endsWith("/")) {
						key = uploadAnnotation.key() + key;
					} else {
						key = uploadAnnotation.key();
					}
				}
				try {
					if (uploadAnnotation.asyn()) {
						uploadResult = cosObjectManager.asynchUpload(bucketName, key, (File) arguments[0]);
					} else {
						uploadResult = cosObjectManager.synchUpload(bucketName, key, (File) arguments[0]);
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			} else if (arguments[0] instanceof PutObjectRequest) {
				try {
					if (uploadAnnotation.asyn()) {
						uploadResult = cosObjectManager.asynchUpload((PutObjectRequest) arguments[0]);
					} else {
						uploadResult = cosObjectManager.synchUpload((PutObjectRequest) arguments[0]);
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			} else {
				try {
					//将对象写到流里
					ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
					ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
					objOut.writeObject(arguments[0]);
					//从流里读出来
					ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
					ObjectInputStream objInput = new ObjectInputStream(byteIn);
					ObjectMetadata metadata = new ObjectMetadata();
					metadata.addUserMetadata("type", method.getParameterTypes()[0].getTypeName());
					PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, uploadAnnotation.key(), objInput, metadata);
					if (uploadAnnotation.asyn()) {
						uploadResult = cosObjectManager.asynchUpload(putObjectRequest);
					} else {
						uploadResult = cosObjectManager.synchUpload(putObjectRequest);
					}
				} catch (IOException e) {
					e.printStackTrace();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		} else {
			try {
				if (arguments.length == 3 && arguments[0] instanceof String && arguments[1] instanceof String && arguments[2] instanceof File) {
					if (uploadAnnotation.asyn()) {
						uploadResult = cosObjectManager.asynchUpload((String) arguments[0], (String) arguments[1], (File) arguments[2]);
					} else {
						uploadResult = cosObjectManager.synchUpload((String) arguments[0], (String) arguments[1], (File) arguments[2]);
					}
				}
				if (arguments.length == 4 && arguments[0] instanceof String && arguments[1] instanceof String
						&& arguments[2] instanceof InputStream && arguments[3] instanceof ObjectMetadata) {
					if (uploadAnnotation.asyn()) {
						uploadResult = cosObjectManager.asynchUpload((String) arguments[0],
								(String) arguments[1], (InputStream) arguments[2], (ObjectMetadata) arguments[2]);
					} else {
						uploadResult = cosObjectManager.synchUpload((String) arguments[0],
								(String) arguments[1], (InputStream) arguments[2], (ObjectMetadata) arguments[2]);
					}
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		for (Object argument : arguments) {
			if (argument instanceof File) {
				boolean delete = ((File) argument).delete();
			}
		}
		if (method.getGenericReturnType().getTypeName().equals(UploadResult.class.getTypeName())) {
			return uploadResult;
		}
		if (method.getGenericReturnType().getTypeName().equals(Object.class.getTypeName())) {
			return uploadResult;
		}
		if (method.getGenericReturnType().getTypeName().equals(String.class.getTypeName())) {
			return uploadResult.toString();
		}
		return ret;
	}

	@Before("downloadAspectMethod()")
	public void downloadBefore(JoinPoint joinPoint) {
		MethodSignature signature = (MethodSignature) joinPoint.getSignature();
		Object[] args = joinPoint.getArgs();
		Method method = signature.getMethod();
		Class<?> targetClass = joinPoint.getTarget().getClass();
		UseCOS useBucketAnnotation = AnnotationUtils.findAnnotation(targetClass, UseCOS.class);
		Download downloadAnnotation = AnnotationUtils.findAnnotation(method, Download.class);
		String bucketName = DefaultBuckets.bucket;
		if (useBucketAnnotation.bucketName() != null && !"".equals(useBucketAnnotation.bucketName())) {
			bucketName = useBucketAnnotation.bucketName();
		}
		if (downloadAnnotation.bucketName() != null && !"".equals(downloadAnnotation.bucketName())) {
			bucketName = downloadAnnotation.bucketName();
		}
		if ("".equals(bucketName)) {
			throw new NoBucketExeception();
		}
		if (args.length == 1) {
			if (args[0] instanceof File) {
				if ("".equals(downloadAnnotation.key())) {
					throw new NoKeyException();
				}
				try {
					if (downloadAnnotation.asyn()) {
						cosObjectManager.asynchDownload(bucketName, downloadAnnotation.key(), (File) args[0]);
					} else {
						cosObjectManager.synchDownload(bucketName, downloadAnnotation.key(), (File) args[0]);
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			} else if (args[0] instanceof DownObjectRequest) {
				DownObjectRequest arg = (DownObjectRequest) args[0];
				if (arg.getBucketName() == null || "".equals(arg.getBucketName())) {
					arg.setBucketName(bucketName);
				}
				if ((arg.getKey() == null || "".equals(arg.getKey())) && "".equals(downloadAnnotation.key())) {
					throw new NoKeyException();
				} else if (arg.getKey() == null || "".equals(arg.getKey())) {
					arg.setKey(downloadAnnotation.key());
				}
				if (arg.getFileName() == null || "".equals(arg.getFileName())){
					arg.setFileName(downloadAnnotation.key());
				}
				File dir = new File(arg.getToPath());
				// 判断文件目录是否存在
				if (!dir.exists() && dir.isDirectory()) {
					dir.mkdirs();
				}
				File file = new File(arg.getToPath(), arg.getFileName());
				if (!file.exists()){
					try {
						file.createNewFile();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				try {
					if (downloadAnnotation.asyn()) {
						cosObjectManager.asynchDownload(arg, file);
					} else {
						cosObjectManager.synchDownload(arg, file);
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

	@Before("downloadRemoveSreAspectMethod()")
	public void downloadRemoveSreBefore(JoinPoint joinPoint) {
		MethodSignature signature = (MethodSignature) joinPoint.getSignature();
		Object[] args = joinPoint.getArgs();
		Method method = signature.getMethod();
		Class<?> targetClass = joinPoint.getTarget().getClass();
		UseCOS useBucketAnnotation = AnnotationUtils.findAnnotation(targetClass, UseCOS.class);
		DownloadRemoveSrc downloadAnnotation = AnnotationUtils.findAnnotation(method, DownloadRemoveSrc.class);
		String bucketName = DefaultBuckets.bucket;
		if (useBucketAnnotation.bucketName() != null && !"".equals(useBucketAnnotation.bucketName())) {
			bucketName = useBucketAnnotation.bucketName();
		}
		if (downloadAnnotation.bucketName() != null && !"".equals(downloadAnnotation.bucketName())) {
			bucketName = downloadAnnotation.bucketName();
		}
		if ("".equals(bucketName)) {
			throw new NoBucketExeception();
		}
		if (args.length == 1) {
			if (args[0] instanceof File) {
				if ("".equals(downloadAnnotation.key())) {
					throw new NoKeyException();
				}
				try {
					if (downloadAnnotation.asyn()) {
						cosObjectManager.asynchDownload(bucketName, downloadAnnotation.key(), (File) args[0]);
					} else {
						cosObjectManager.synchDownload(bucketName, downloadAnnotation.key(), (File) args[0]);
					}
					cosObjectManager.deleteObject(bucketName, downloadAnnotation.key());
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			} else if (args[0] instanceof DownObjectRequest) {
				DownObjectRequest arg = (DownObjectRequest) args[0];
				if (arg.getBucketName() == null || "".equals(arg.getBucketName())) {
					arg.setBucketName(bucketName);
				}
				if ((arg.getKey() == null || "".equals(arg.getKey())) && "".equals(downloadAnnotation.key())) {
					throw new NoKeyException();
				} else if (arg.getKey() == null || "".equals(arg.getKey())) {
					arg.setKey(downloadAnnotation.key());
				}
				if (arg.getFileName() == null || "".equals(arg.getFileName())){
					arg.setFileName(downloadAnnotation.key());
				}
				File dir = new File(arg.getToPath());
				// 判断文件目录是否存在
				if (!dir.exists() && dir.isDirectory()) {
					dir.mkdirs();
				}
				File file = new File(arg.getToPath(), arg.getFileName());
				if (!file.exists()){
					try {
						file.createNewFile();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				try {
					if (downloadAnnotation.asyn()) {
						cosObjectManager.asynchDownload(arg, file);
					} else {
						cosObjectManager.synchDownload(arg, file);
					}
					cosObjectManager.deleteObject(bucketName, downloadAnnotation.key());
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

	@Around("useBucketAspect()")
	public Object useBucketAspectAround(ProceedingJoinPoint joinPoint) {
		MethodSignature signature = (MethodSignature) joinPoint.getSignature();
		Object[] args = joinPoint.getArgs();
		Method method = signature.getMethod();
		Parameter[] parameters = method.getParameters();
		Object target = joinPoint.getTarget();
		Class<?> targetClass = target.getClass();
		UseCOS useBucket = AnnotationUtils.findAnnotation(targetClass, UseCOS.class);
		String bucketName = DefaultBuckets.bucket;
		if (useBucket.bucketName() != null && !"".equals(useBucket.bucketName())) {
			bucketName = useBucket.bucketName();
		}
		serviceInjectProcessor.postProcessAfterInitialization(target,targetClass.getName());
		for (int i = 0; i < parameters.length; i++) {
			Parameter parameter = parameters[i];
			Annotation[] declaredAnnotations = parameter.getDeclaredAnnotations();
			for (Annotation declaredAnnotation : declaredAnnotations) {
				if (declaredAnnotation instanceof Download) {
					Download download = AnnotationUtils.findAnnotation(parameter, Download.class);
					bucketName = "".equals(download.bucketName()) ? bucketName : download.bucketName();
					if ("".equals(bucketName)) {
						throw new NoBucketExeception();
					}
					if (args[i] instanceof File) {
						if ("".equals(download.key())) {
							throw new NoKeyException();
						}
						try {
							File file = (File) args[i];
							if (file == null || "".equals(file.getAbsolutePath())) {
								file = new File(download.key());
							}
							if (!file.exists()) {
								file.createNewFile();
							}
							if (download.asyn()) {
								cosObjectManager.asynchDownload(bucketName, download.key(), file);
							} else {
								cosObjectManager.synchDownload(bucketName, download.key(), file);
							}
							args[i] = file;
						} catch (InterruptedException e) {
							e.printStackTrace();
						} catch (IOException e) {
							e.printStackTrace();
						}
					} else if (args[i] instanceof DownObjectRequest) {
						DownObjectRequest arg = (DownObjectRequest) args[i];
						if (arg.getBucketName() == null || "".equals(arg.getBucketName())) {
							arg.setBucketName(bucketName);
						}
						if ((arg.getKey() == null || "".equals(arg.getKey())) && "".equals(download.key())) {
							throw new NoKeyException();
						} else if (arg.getKey() == null || "".equals(arg.getKey())) {
							arg.setKey(download.key());
						}
						if (arg.getFileName() == null || "".equals(arg.getFileName())){
							arg.setFileName(download.key());
						}
						File dir = new File(arg.getToPath());
						// 判断文件目录是否存在
						if (!dir.exists() && dir.isDirectory()) {
							dir.mkdirs();
						}
						File file = new File(arg.getToPath(), arg.getFileName());
						if (!file.exists()){
							try {
								file.createNewFile();
							} catch (IOException e) {
								e.printStackTrace();
							}
						}
						try {
							if (download.asyn()) {
								cosObjectManager.asynchDownload(arg, file);
							} else {
								cosObjectManager.synchDownload(arg, file);
							}
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}else if (args[i] instanceof InputStream) {
						COSObject object = cosObjectManager.getObject(bucketName, download.key());
						args[i] = object.getObjectContent();
					} else {
						throw new NonacceptanceException();
					}
				}
				if (declaredAnnotation instanceof DownloadRemoveSrc) {
					DownloadRemoveSrc downloadRemoveSrc = AnnotationUtils.findAnnotation(parameter, DownloadRemoveSrc.class);
					bucketName = "".equals(downloadRemoveSrc.bucketName()) ? bucketName : downloadRemoveSrc.bucketName();
					if ("".equals(bucketName)) {
						throw new NoBucketExeception();
					}
					if (args[i] instanceof File) {
						if ("".equals(downloadRemoveSrc.key())) {
							throw new NoKeyException();
						}
						try {
							File file = (File) args[i];
							if (file == null || "".equals(file.getAbsolutePath())) {
								file = new File(downloadRemoveSrc.key());
							}
							if (!file.exists()) {
								file.createNewFile();
							}
							if (downloadRemoveSrc.asyn()) {
								cosObjectManager.asynchDownload(bucketName, downloadRemoveSrc.key(), file);
								cosObjectManager.deleteObject(bucketName, downloadRemoveSrc.key());
							} else {
								cosObjectManager.synchDownload(bucketName, downloadRemoveSrc.key(), file);
								cosObjectManager.deleteObject(bucketName, downloadRemoveSrc.key());
							}
							args[i] = file;
						} catch (InterruptedException e) {
							e.printStackTrace();
						} catch (IOException e) {
							e.printStackTrace();
						}
					}else if (args[i] instanceof DownObjectRequest) {
						DownObjectRequest arg = (DownObjectRequest) args[i];
						if (arg.getBucketName() == null || "".equals(arg.getBucketName())) {
							arg.setBucketName(bucketName);
						}
						if ((arg.getKey() == null || "".equals(arg.getKey())) && "".equals(downloadRemoveSrc.key())) {
							throw new NoKeyException();
						} else if (arg.getKey() == null || "".equals(arg.getKey())) {
							arg.setKey(downloadRemoveSrc.key());
						}
						if (arg.getFileName() == null || "".equals(arg.getFileName())){
							arg.setFileName(downloadRemoveSrc.key());
						}
						File dir = new File(arg.getToPath());
						// 判断文件目录是否存在
						if (!dir.exists() && dir.isDirectory()) {
							dir.mkdirs();
						}
						File file = new File(arg.getToPath(), arg.getFileName());
						if (!file.exists()){
							try {
								file.createNewFile();
							} catch (IOException e) {
								e.printStackTrace();
							}
						}
						try {
							if (downloadRemoveSrc.asyn()) {
								cosObjectManager.asynchDownload(arg, file);
							} else {
								cosObjectManager.synchDownload(arg, file);
							}
							cosObjectManager.deleteObject(bucketName, downloadRemoveSrc.key());
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					} else if (args[i] instanceof InputStream) {
						COSObject object = cosObjectManager.getObject(bucketName, downloadRemoveSrc.key());
						args[i] = object.getObjectContent();
						cosObjectManager.deleteObject(bucketName, downloadRemoveSrc.key());
					} else {
						throw new NonacceptanceException();
					}
				}
				if (declaredAnnotation instanceof Upload) {
					Upload upload = AnnotationUtils.findAnnotation(parameter, Upload.class);
					bucketName = "".equals(upload.bucketName()) ? bucketName : upload.bucketName();
					if ("".equals(bucketName)) {
						throw new NoBucketExeception();
					}
					if ("".equals(upload.key())) {
						throw new NoKeyException();
					}
					if (args[i] instanceof File) {
						try {
							File file = (File) args[i];
							String key = file.getName();
							if (!"".equals(upload.key())) {
								if (upload.key().endsWith("/")) {
									key = upload.key() + key;
								} else {
									key = upload.key();
								}
							}
							if (file == null) {
								throw new NoFileException();
							}
							if (!file.exists()) {
								throw new NoFileException();
							}
							if (upload.asyn()) {
								cosObjectManager.asynchUpload(bucketName, key, file);
							} else {
								cosObjectManager.synchUpload(bucketName, key, file);
							}
							args[i] = file;
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					} else if (args[i] instanceof InputStream) {
						ObjectMetadata metadata = new ObjectMetadata();
						try {
							if (upload.asyn()) {
								cosObjectManager.asynchUpload(bucketName, upload.key(), (InputStream) args[i], metadata);
							} else {
								cosObjectManager.synchUpload(bucketName, upload.key(), (InputStream) args[i], metadata);
							}
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					} else {
						throw new NonacceptanceException();
					}
				}
				if (declaredAnnotation instanceof UploadRemoveSrc) {
					UploadRemoveSrc uploadRemoveSrc = AnnotationUtils.findAnnotation(parameter, UploadRemoveSrc.class);
					bucketName = "".equals(uploadRemoveSrc.bucketName()) ? bucketName : uploadRemoveSrc.bucketName();
					if ("".equals(bucketName)) {
						throw new NoBucketExeception();
					}
					if ("".equals(uploadRemoveSrc.key())) {
						throw new NoKeyException();
					}
					if (args[i] instanceof File) {
						try {
							File file = (File) args[i];
							String key = file.getName();
							if (!"".equals(uploadRemoveSrc.key())) {
								if (uploadRemoveSrc.key().endsWith("/")) {
									key = uploadRemoveSrc.key() + key;
								} else {
									key = uploadRemoveSrc.key();
								}
							}
							if (file == null) {
								throw new NoFileException();
							}
							if (!file.exists()) {
								throw new NoFileException();
							}
							if (uploadRemoveSrc.asyn()) {
								cosObjectManager.asynchUpload(bucketName, key, file);
								file.delete();
							} else {
								cosObjectManager.synchUpload(bucketName, key, file);
								file.delete();
							}
							args[i] = file;
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					} else if (args[i] instanceof InputStream) {
						ObjectMetadata metadata = new ObjectMetadata();
						try {
							if (uploadRemoveSrc.asyn()) {
								cosObjectManager.asynchUpload(bucketName, uploadRemoveSrc.key(), (InputStream) args[i], metadata);
							} else {
								cosObjectManager.synchUpload(bucketName, uploadRemoveSrc.key(), (InputStream) args[i], metadata);
							}
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					} else {
						throw new NonacceptanceException();
					}
				}
			}
		}
		Object proceed = null;
		try {
			proceed = joinPoint.proceed(args);
		} catch (Throwable throwable) {
			throwable.printStackTrace();
		}
		return proceed;
	}

}
